package org.zebra.common.util;

import cn.hutool.core.io.FileUtil;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.springframework.http.MediaType;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

/**
 * @author zhanghongbin
 */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class FilePlusUtil extends FileUtil {

    /**
     * 下载文件名重新编码
     *
     * @param response 响应对象
     * @param fileName 真实文件名
     */
    public static void setAttachmentResponseHeader(HttpServletResponse response, String fileName) {
        String percentEncodedFileName = percentEncode(fileName);
        String contentDispositionValue = String.format(
                "attachment; filename=%s;filename*=utf-8''%s", percentEncodedFileName, percentEncodedFileName);
        response.addHeader("Access-Control-Expose-Headers", "Content-Disposition,download-filename");
        response.setHeader("Content-disposition", contentDispositionValue);
        response.setHeader("download-filename", percentEncodedFileName);
        response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE + "; charset=UTF-8");
    }

    public static void download(HttpServletResponse response, String fileName, InputStream inputStream) {
        setAttachmentResponseHeader(response, fileName);
        BufferedInputStream bufferedInputStream = null;
        BufferedOutputStream bufferedOutputStream = null;
        ServletOutputStream outputStream = null;
        try {
            bufferedInputStream = new BufferedInputStream(inputStream);
            // 创建响应输出流
            outputStream = response.getOutputStream();
            bufferedOutputStream = new BufferedOutputStream(outputStream);
            // 分块传输文件
            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = bufferedInputStream.read(buffer)) != -1) {
                bufferedOutputStream.write(buffer, 0, bytesRead);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (bufferedOutputStream != null) {
                    bufferedOutputStream.flush();
                }
                if (bufferedInputStream != null) {
                    bufferedInputStream.close();
                }
                if (outputStream != null) {
                    outputStream.close();
                }
            } catch (Exception e) {
            }
        }
    }

    public static void download(HttpServletResponse response, String fileName, byte[] bytes) {
        setAttachmentResponseHeader(response, fileName);
        ByteArrayInputStream byteArrayInputStream = null;
        BufferedOutputStream bufferedOutputStream = null;
        ServletOutputStream outputStream = null;
        try {
            byteArrayInputStream = new ByteArrayInputStream(bytes);
            // 创建响应输出流
            outputStream = response.getOutputStream();
            bufferedOutputStream = new BufferedOutputStream(outputStream);
            // 分块传输文件
            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = byteArrayInputStream.read(buffer)) != -1) {
                bufferedOutputStream.write(buffer, 0, bytesRead);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (bufferedOutputStream != null) {
                    bufferedOutputStream.flush();
                }
                if (byteArrayInputStream != null) {
                    byteArrayInputStream.close();
                }
                if (outputStream != null) {
                    outputStream.close();
                }
            } catch (Exception e) {
            }
        }
    }

    /**
     * 百分号编码工具方法
     *
     * @param s 需要百分号编码的字符串
     * @return 百分号编码后的字符串
     */
    public static String percentEncode(String s) {
        String encode = URLEncoder.encode(s, StandardCharsets.UTF_8);
        return encode.replaceAll("\\+", "%20");
    }
}
